#!/export/home/mahdi/pyenvs/t1/bin/python
    #!/usr/bin/env python


from __future__ import print_function
import subprocess as sp
import time
import shlex as sx
import os 
import sys
from threading import Thread
import multiprocessing as mp
from Queue import Queue as Q
import argparse
import logging


__SPACE_MARKER = '!$#!_$#**_'

#def grep(pattern, safe_full_path, val, lock):
def grep():

    while True:
        try:
            workdata = que.get()
            oldcommand = sx.split('grep {0} {1}'.format(workdata['pattern'], workdata['safe_full_path']))
            command = undoMakeSafeFIle(oldcommand)
            ps = sp.Popen(command, stdout=sp.PIPE, stderr=sp.PIPE)
            stdout, stderr = ps.communicate()
            retc = ps.returncode
            #with lock:
            #    val.value += 1
            if stdout:
                print('file w/match: {0}'.format(safe_full_path))
            if stderr and retc != 0:
                print('ERROR: {0}'.format(stderr, file=sys.stderr))
            #print(ps.stdout.read(), end=' ')
        except Exception, e:
            print(e)
            if type(e) == KeyboardInterrupt:
                print('\t\tKEYBOARD INTERRUPT')
                sys.exit(1)
                raise KeyboardInterrupt
            pass
        finally:
            que.task_done()


def checkRange(arg):
    try:
        value = int(arg)
    except argparse.ArgumentTypeError, e:
        print(str(e), stderr=sys.stderr)
    if value <= 0 or value > 12:
        raise argparse.ArgumentTypeError('must be in range: {1 <= value <= 12}')
    return value


def makeSafeFile(unsafe_full_path):
    if unsafe_full_path.find(' ') == -1:
        return unsafe_full_path
    else:
        return unsafe_full_path.replace(' ', __SPACE_MARKER)

def undoMakeSafeFIle(cmdlist):
    return [ci.replace(__SPACE_MARKER, ' ') for ci in cmdlist]



if __name__ == '__main__':
    start = time.time()
    parser = argparse.ArgumentParser()
    parser.add_argument('pattern', help='search pattern')
    parser.add_argument('directory', help='the root directory to start the search in')
    parser.add_argument('-c', '--cores', type=checkRange, help='number of cores to use in search', default=4)
    #parser.add_argument('--cores', help='will try to use this many cores')
    args = parser.parse_args()
    #que = Q(args.cores)
    global que
    que = Q(maxsize=2000)
    #manager = mp.Manager()
    #val = manager.Value('i', 0)
    #lock = manager.Lock()
    #START THREADS AND WAIT FOR QUE DISPATCH
    for i in range(60):
        #t = Thread(target=grep, args=(que))
        t = Thread(target=grep)
        t.daemon = True
        t.start()

    try:
        for root, dirs, fyles in os.walk(args.directory):
            for fyle in fyles:
                unsafe_full_path = os.path.join(root, fyle)
                safe_full_path = makeSafeFile(unsafe_full_path)
                que.put({'pattern': args.pattern, 'safe_full_path': safe_full_path})
        que.join()
        #pool.close()
        #pool.join()
    except KeyboardInterrupt, e:
        print('\t\t**INTERRUPTED**')
        sys.exit(1)
    end = time.time()
    print('{0}{1}cores used: {2}'.format('\n'*2, '\t', args.cores))
    #print('{0}{1}files processed: {2}'.format('\n'*2, '\t', val.value))
    print('{0}{1}finished in: {2} seconds'.format('\n'*2, '\t', end-start))

